package edu.geo.db.conn;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.SQLException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Permite gestionar las conexiones a la base de datos.
 * 
 * 
 */
public abstract class DBConnectionProvider implements Serializable
{
	/**
	 * 
	 */
	private static final long serialVersionUID = -9000139476139532544L;
	/**
	 * 
	 */
	static private final Log LOGGER = LogFactory.getLog(DBConnection.class);
	
	/**
	 * Obtener una conexión a la base de datos configurada. Este método debe ser implementado
	 * por la clase que herede de esta clase.
	 * 
	 * @return Una conexión a la base de datos configuradada.
	 * 
	 * @throws SQLException Una excepción en caso que un error haya ocurrido.
	 */
	public abstract Connection getConnection() throws SQLException;
	
	/**
	 * Permite cerrar los recursos de bases de datos utilizados para interactúar con ella.
	 * 
	 * @param args Lista de objetos que deben cerrarse. 
	 * 
	 * @return Un conjunto de excepciones en caso de que estas ocurran.
	 */
	public static Throwable close(Object... args)
	{
		Throwable toThrow = null;
		for (Object item : args)
		{
			if (item == null)
			{
				continue;
			}
			try
			{
				Method closeMethod = item.getClass().getMethod("close",
						(Class[]) null);
				try
				{
				    closeMethod.setAccessible( true );
					closeMethod.invoke(item, (Object[]) null);
				}
				catch (InvocationTargetException tExc)
				{
					Throwable e = tExc.getCause();
					if (toThrow != null)
					{
						e.initCause(toThrow);
						LOGGER.error(e.getMessage(), e);
					}
					toThrow = e;
				}
			}
			catch (IllegalArgumentException e)
			{
				LOGGER.error(e.getMessage(), e);
			}
			catch (IllegalAccessException e)
			{
				LOGGER.error(e.getMessage(), e);
			}
			catch (NoSuchMethodException e)
			{
				LOGGER.error(e.getMessage(), e);
				
			}
		}
		return toThrow;
	}
}
